﻿
using System.Security.Cryptography;
using System.Text;
using CMB_PAY;
using Newtonsoft.Json;

internal class Program
{
    private const string MER_ID = "30899917273018Q"; // 招商银行商户号（注意：接入联调时需改成接入时提供的商户号）
    private const string USER_ID = "V078502606"; // 招商银行收银员（注意：接入联调时需改成接入时提供的收银员）

    private const string APPID = "8ab74856-8772-45c9-96db-54cb30ab9f74"; // header中的APPID
    private const string APP_SECRET = "5b96f20a-011f-4254-8be8-9a5ceb2f317f"; // 用于生成header中的APISign

    // 微信公众号支付相关参数
    private const string SUB_APPID = "wxa086211a969ddb48";//   wxa086211a969ddb48   
    private const string SUB_OPENID = "817817e39146508601128c30116e2e99"; //817817e39146508601128c30116e2e99

    public static class ApiUrl
    {
        /// <summary> 收款码申请 </summary>
        public static string Url_Qrcodeapply = "https://api.cmburl.cn:8065/polypay/v1.0/mchorders/qrcodeapply";

        /// <summary> 微信统一下单 </summary>
        public static string Url_Onlinepay = "https://api.cmburl.cn:8065/polypay/v1.0/mchorders/onlinepay";

        /// <summary> 订单二维码申请 </summary>
        public static string Url_Orderqrcodeapply = "https://api.cmburl.cn:8065/polypay/v1.0/mchorders/orderqrcodeapply";

        /// <summary> 支付宝窗支付 </summary>
        public static string Url_Servpay = "https://api.cmburl.cn:8065/polypay/v1.0/mchorders/servpay";

        /// <summary> 支付宝native支付 </summary>
        public static string Url_Zfbqrcode = "https://api.cmburl.cn:8065/polypay/v1.0/mchorders/zfbqrcode";

        /// <summary> 退款申请 </summary>
        public static string Url_Refund = "https://api.cmburl.cn:8065/polypay/v1.0/mchorders/refund";

        /// <summary> 退款申请结果查询 </summary>
        public static string Url_Refundquery = "https://api.cmbchina.com/polypay/v1.0/mchorders/refundquery";

        /// <summary> 支付结果查询 </summary>
        public static string Url_Orderquery = "https://api.cmburl.cn:8065/polypay/v1.0/mchorders/orderquery";
    }

    private static async Task Main(string[] args)
    {
        //MchordersQrcodeapply(); //收款码申请

        //MchordersOnlinepay(); //微信统一下单

        //MchordersOrderqrcodeapply(); //订单二维码申请

        //MchordersServpay(); //支付宝窗支付

        //MchordersZfbqrcode(); //支付宝native支付

        MchordersRefund(); //退款申请

        //MchordersRefundquery();//退款申请结果查询

        //MchordersOrderquery(); //支付结果查询
    }

    /// <summary>
    /// 收款码申请
    /// </summary>
    public static void MchordersQrcodeapply()
    {
        Dictionary<String, String> sortedParams = new Dictionary<string, string>();
        sortedParams.Add("version", "0.0.1"); //版本号
        sortedParams.Add("encoding", "UTF-8"); //编码方式
        sortedParams.Add("signMethod", "02"); //签名方法

        Dictionary<string, string> bizContent = new Dictionary<string, string>();

        bizContent.Add("merId", MER_ID); //商户号
        bizContent.Add("orderId", "3089991074200OHtest1026271"); //商户订单号
        bizContent.Add("userId", USER_ID); //收银员
        bizContent.Add("notifyUrl", "https://qa-openapi.youzy.cn/youzy.tob.payment.order.cmb.notify"); //交易通知地址                           
        bizContent.Add("txnAmt", "1"); //交易金额

        //bizContent.Add("body", "body"); //商品描述
        //bizContent.Add("tradeType", "JSAPI");  //交易类型    
        //bizContent.Add("tradeScene", "OFFLINE"); //交易场景   
        //bizContent.Add("spbillCreateIp", "127.0.0.1");
        //bizContent.Add("deviceInfo", "WEB"); //不是必传参数，PC 网页或公众号内支付请传"WEB"  
        //bizContent.Add("subAppId", SUB_APPID);
        //bizContent.Add("subOpenId", SUB_OPENID);

        //排序
        bizContent = bizContent.OrderBy(m => m.Key).ToDictionary(p => p.Key, o => o.Value);

        sortedParams.Add("biz_content", JsonConvert.SerializeObject(bizContent));

        sortedParams.Add("sign", GetSign(sortedParams));

        Console.WriteLine("请求参数:");
        Console.WriteLine(JsonConvert.SerializeObject(sortedParams));
        Console.WriteLine("请求头:");
        Console.WriteLine(JsonConvert.SerializeObject(GetHeader(sortedParams)));

        Dictionary<string, string> result = CMB_WebUtil.PostForEntity(ApiUrl.Url_Qrcodeapply, JsonConvert.SerializeObject(sortedParams), GetHeader(sortedParams));

        Console.WriteLine("响应参数:");
        Console.WriteLine(JsonConvert.SerializeObject(result));

        // 验签
        CMB_SignUtil.VerifySign(result);
    }

    /// <summary>
    /// 微信统一下单
    /// </summary>
    public static void MchordersOnlinepay()
    {
        var wechat_h5 = new wechat_h5();
        var h5_info = new h5_info();
        h5_info.type = "h5_info";
        h5_info.wap_url = "http://qa-bh5v.youzy.cn/";
        h5_info.wap_name = "优家志愿填报";
        wechat_h5.h5_info = h5_info;

        Dictionary<String, String> sortedParams = new Dictionary<string, string>();
        sortedParams.Add("version", "0.0.1");
        sortedParams.Add("encoding", "UTF-8");
        sortedParams.Add("signMethod", "02");

        Dictionary<string, string> bizContent = new Dictionary<string, string>();

        bizContent.Add("merId", MER_ID);
        bizContent.Add("deviceInfo", "WEB"); //不是必传参数，PC 网页或公众号内支付请传"WEB"
        bizContent.Add("subAppId", SUB_APPID);
        bizContent.Add("orderId", "QY2023111515280019");
        bizContent.Add("tradeType", "JSAPI");
        bizContent.Add("subOpenId", "ognj2jklyMYi_SaR-z8Sk5_-8sZo");
        bizContent.Add("sceneInfo", JsonConvert.SerializeObject(wechat_h5));


        bizContent.Add("userId", USER_ID);
        bizContent.Add("body", "body");
        bizContent.Add("notifyUrl", "https://qa-openapi.youzy.cn/youzy.tob.payment.order.cmb.notify"); //通知地址
        bizContent.Add("txnAmt", "1");
        bizContent.Add("spbillCreateIp", "127.0.0.1");

        //bizContent.Add("tradeScene", "OFFLINE");
        //bizContent.Add("subOpenId", SUB_APPID);

        //排序
        bizContent = bizContent.OrderBy(m => m.Key).ToDictionary(p => p.Key, o => o.Value);

        sortedParams.Add("biz_content", JsonConvert.SerializeObject(bizContent));

        sortedParams.Add("sign", CMB_SignUtil.GetSign(sortedParams));

        Console.WriteLine("请求参数:");
        Console.WriteLine(JsonConvert.SerializeObject(sortedParams));
        Console.WriteLine("请求头:");
        Console.WriteLine(JsonConvert.SerializeObject(GetHeader(sortedParams)));

        Dictionary<string, string> result = CMB_WebUtil.PostForEntity(ApiUrl.Url_Onlinepay, JsonConvert.SerializeObject(sortedParams), GetHeader(sortedParams));

        Console.WriteLine("响应参数:");
        Console.WriteLine(JsonConvert.SerializeObject(result));

        // 验签
        CMB_SignUtil.VerifySign(result);
    }

    /// <summary>
    /// 订单二维码申请
    /// </summary>
    public static void MchordersOrderqrcodeapply()
    {
        Dictionary<String, String> sortedParams = new Dictionary<string, string>();
        sortedParams.Add("version", "0.0.1"); //版本号
        sortedParams.Add("encoding", "UTF-8"); //编码方式
        sortedParams.Add("signMethod", "02"); //签名方法

        Dictionary<string, string> bizContent = new Dictionary<string, string>();

        bizContent.Add("merId", MER_ID); //商户号
        bizContent.Add("orderId", "3089991074200OHtest1026311"); //商户订单号
        bizContent.Add("userId", USER_ID); //收银员
        bizContent.Add("notifyUrl", "https://qa-openapi.youzy.cn/youzy.tob.payment.order.cmb.notify"); //交易通知地址                           
        bizContent.Add("txnAmt", "1"); //交易金额

        bizContent.Add("sceneInfo", ""); //场景信息


        //bizContent.Add("body", "body"); //商品描述
        //bizContent.Add("tradeType", "JSAPI");  //交易类型    
        //bizContent.Add("tradeScene", "OFFLINE"); //交易场景   
        //bizContent.Add("spbillCreateIp", "127.0.0.1");
        //bizContent.Add("deviceInfo", "WEB"); //不是必传参数，PC 网页或公众号内支付请传"WEB"  
        //bizContent.Add("subAppId", SUB_APPID);
        //bizContent.Add("subOpenId", SUB_OPENID);

        //排序
        bizContent = bizContent.OrderBy(m => m.Key).ToDictionary(p => p.Key, o => o.Value);

        sortedParams.Add("biz_content", JsonConvert.SerializeObject(bizContent));

        sortedParams.Add("sign", GetSign(sortedParams));

        Console.WriteLine("请求参数:");
        Console.WriteLine(JsonConvert.SerializeObject(sortedParams));
        Console.WriteLine("请求头:");
        Console.WriteLine(JsonConvert.SerializeObject(GetHeader(sortedParams)));

        Dictionary<string, string> result = CMB_WebUtil.PostForEntity(ApiUrl.Url_Orderqrcodeapply, JsonConvert.SerializeObject(sortedParams), GetHeader(sortedParams));

        Console.WriteLine("响应参数:");
        Console.WriteLine(JsonConvert.SerializeObject(result));

        // 验签
        CMB_SignUtil.VerifySign(result);

    }

    /// <summary>
    /// 支付宝窗支付
    /// </summary>
    public static void MchordersServpay()
    {
        Dictionary<String, String> sortedParams = new Dictionary<string, string>();
        sortedParams.Add("version", "0.0.1"); //版本号
        sortedParams.Add("encoding", "UTF-8"); //编码方式
        sortedParams.Add("signMethod", "02"); //签名方法

        Dictionary<string, string> bizContent = new Dictionary<string, string>();

        bizContent.Add("merId", MER_ID); //商户号
        bizContent.Add("orderId", "3089991074200OHtest1026601"); //商户订单号
        bizContent.Add("userId", USER_ID); //收银员
        bizContent.Add("notifyUrl", "https://qa-openapi.youzy.cn/youzy.tob.payment.order.cmb.notify"); //交易通知地址                           
        bizContent.Add("txnAmt", "1"); //交易金额

        //bizContent.Add("body", "body"); //商品描述
        //bizContent.Add("tradeType", "JSAPI");  //交易类型    
        //bizContent.Add("tradeScene", "OFFLINE"); //交易场景   
        //bizContent.Add("spbillCreateIp", "127.0.0.1");
        //bizContent.Add("deviceInfo", "WEB"); //不是必传参数，PC 网页或公众号内支付请传"WEB"  
        //bizContent.Add("subAppId", SUB_APPID);
        //bizContent.Add("subOpenId", SUB_OPENID);

        //排序
        bizContent = bizContent.OrderBy(m => m.Key).ToDictionary(p => p.Key, o => o.Value);

        sortedParams.Add("biz_content", JsonConvert.SerializeObject(bizContent));

        sortedParams.Add("sign", CMB_SignUtil.GetSign(sortedParams));

        Console.WriteLine("请求参数:");
        Console.WriteLine(JsonConvert.SerializeObject(sortedParams));
        Console.WriteLine("请求头:");
        Console.WriteLine(JsonConvert.SerializeObject(GetHeader(sortedParams)));

        Dictionary<string, string> result = CMB_WebUtil.PostForEntity(ApiUrl.Url_Servpay, JsonConvert.SerializeObject(sortedParams), GetHeader(sortedParams));

        Console.WriteLine("响应参数:");
        Console.WriteLine(JsonConvert.SerializeObject(result));

        // 验签
        CMB_SignUtil.VerifySign(result);
    }

    /// <summary>
    /// 支付宝native支付
    /// </summary>
    public static void MchordersZfbqrcode()
    {
        Dictionary<String, String> sortedParams = new Dictionary<string, string>();
        sortedParams.Add("version", "0.0.1"); //版本号
        sortedParams.Add("encoding", "UTF-8"); //编码方式
        sortedParams.Add("signMethod", "02"); //签名方法

        Dictionary<string, string> bizContent = new Dictionary<string, string>();

        bizContent.Add("merId", MER_ID); //商户号
        bizContent.Add("orderId", "PO202311101714430288"); //商户订单号
        bizContent.Add("userId", USER_ID); //收银员
        bizContent.Add("notifyUrl", "https://qa-openapi.youzy.cn/youzy.tob.payment.order.cmb.notify"); //交易通知地址                           
        bizContent.Add("txnAmt", "1"); //交易金额

        //bizContent.Add("body", "body"); //商品描述
        //bizContent.Add("tradeType", "JSAPI");  //交易类型    
        //bizContent.Add("tradeScene", "OFFLINE"); //交易场景   
        //bizContent.Add("spbillCreateIp", "127.0.0.1");
        //bizContent.Add("deviceInfo", "WEB"); //不是必传参数，PC 网页或公众号内支付请传"WEB"  
        //bizContent.Add("subAppId", SUB_APPID);
        //bizContent.Add("subOpenId", SUB_OPENID);

        //排序
        bizContent = bizContent.OrderBy(m => m.Key).ToDictionary(p => p.Key, o => o.Value);

        sortedParams.Add("biz_content", JsonConvert.SerializeObject(bizContent));

        sortedParams.Add("sign", CMB_SignUtil.GetSign(sortedParams));

        Console.WriteLine("请求参数:");
        Console.WriteLine(JsonConvert.SerializeObject(sortedParams));
        Console.WriteLine("请求头:");
        Console.WriteLine(JsonConvert.SerializeObject(GetHeader(sortedParams)));

        Dictionary<string, string> result = CMB_WebUtil.PostForEntity(ApiUrl.Url_Zfbqrcode, JsonConvert.SerializeObject(sortedParams), GetHeader(sortedParams));

        Console.WriteLine("响应参数:");
        Console.WriteLine(JsonConvert.SerializeObject(result));

        // 验签
        CMB_SignUtil.VerifySign(result);
    }

    /// <summary>
    /// 退款申请
    /// </summary>
    public static void MchordersRefund()
    {
        Dictionary<String, String> sortedParams = new Dictionary<string, string>();
        sortedParams.Add("version", "0.0.1"); //版本号
        sortedParams.Add("encoding", "UTF-8"); //编码方式
        sortedParams.Add("signMethod", "02"); //签名方法

        Dictionary<string, string> bizContent = new Dictionary<string, string>();

        bizContent.Add("merId", MER_ID); //商户号
        bizContent.Add("orderId", "QY2023111515283005"); //商户订单号
        //bizContent.Add("origOrderId", "3089991074200OHtest1026521"); //商户订单号
        bizContent.Add("origCmbOrderId", "004123112017051891328064"); //cmb单号
        bizContent.Add("userId", USER_ID); //收银员
        bizContent.Add("notifyUrl", "https://qa-openapi.youzy.cn/youzy.tob.payment.order.cmb. "); //交易通知地址                           
        bizContent.Add("txnAmt", "1"); //交易金额
        bizContent.Add("refundAmt", "1"); //退款金额

        //bizContent.Add("body", "body"); //商品描述
        //bizContent.Add("tradeType", "JSAPI");  //交易类型    
        //bizContent.Add("tradeScene", "OFFLINE"); //交易场景   
        //bizContent.Add("spbillCreateIp", "127.0.0.1");
        //bizContent.Add("deviceInfo", "WEB"); //不是必传参数，PC 网页或公众号内支付请传"WEB"  
        //bizContent.Add("subAppId", SUB_APPID);
        //bizContent.Add("subOpenId", SUB_OPENID);

        //排序
        bizContent = bizContent.OrderBy(m => m.Key).ToDictionary(p => p.Key, o => o.Value);

        sortedParams.Add("biz_content", JsonConvert.SerializeObject(bizContent));

        sortedParams.Add("sign", CMB_SignUtil.GetSign(sortedParams));

        Console.WriteLine("请求参数:");
        Console.WriteLine(JsonConvert.SerializeObject(sortedParams));
        Console.WriteLine("请求头:");
        Console.WriteLine(JsonConvert.SerializeObject(GetHeader(sortedParams)));

        Dictionary<string, string> result = CMB_WebUtil.PostForEntity(ApiUrl.Url_Refund, JsonConvert.SerializeObject(sortedParams), GetHeader(sortedParams));

        Console.WriteLine("响应参数:");
        Console.WriteLine(JsonConvert.SerializeObject(result));

        // 验签
        CMB_SignUtil.VerifySign(result);
    }

    /// <summary>
    /// 退款申请结果查询
    /// </summary>
    public static void MchordersRefundquery()
    {
        Dictionary<String, String> sortedParams = new Dictionary<string, string>();
        sortedParams.Add("version", "0.0.1"); //版本号
        sortedParams.Add("encoding", "UTF-8"); //编码方式
        sortedParams.Add("signMethod", "02"); //签名方法

        Dictionary<string, string> bizContent = new Dictionary<string, string>();

        bizContent.Add("merId", MER_ID); //商户号
        bizContent.Add("orderId", "3089991074200OHtest1026521"); //商户订单号
        bizContent.Add("cmbOrderId", "004123111615545194102129"); //cmb单号
        bizContent.Add("userId", USER_ID); //收银员

        //bizContent.Add("body", "body"); //商品描述
        //bizContent.Add("tradeType", "JSAPI");  //交易类型    
        //bizContent.Add("tradeScene", "OFFLINE"); //交易场景   
        //bizContent.Add("spbillCreateIp", "127.0.0.1");
        //bizContent.Add("deviceInfo", "WEB"); //不是必传参数，PC 网页或公众号内支付请传"WEB"  
        //bizContent.Add("subAppId", SUB_APPID);
        //bizContent.Add("subOpenId", SUB_OPENID);

        //排序
        bizContent = bizContent.OrderBy(m => m.Key).ToDictionary(p => p.Key, o => o.Value);

        sortedParams.Add("biz_content", JsonConvert.SerializeObject(bizContent));

        sortedParams.Add("sign", CMB_SignUtil.GetSign(sortedParams));

        Console.WriteLine("请求参数:");
        Console.WriteLine(JsonConvert.SerializeObject(sortedParams));
        Console.WriteLine("请求头:");
        Console.WriteLine(JsonConvert.SerializeObject(GetHeader(sortedParams)));

        Dictionary<string, string> result = CMB_WebUtil.PostForEntity(ApiUrl.Url_Refundquery, JsonConvert.SerializeObject(sortedParams), GetHeader(sortedParams));

        Console.WriteLine("响应参数:");
        Console.WriteLine(JsonConvert.SerializeObject(result));

        // 验签
        CMB_SignUtil.VerifySign(result);
    }

    /// <summary>
    /// 支付结果查询
    /// </summary>
    public static void MchordersOrderquery()
    {
        Dictionary<String, String> sortedParams = new Dictionary<string, string>();
        sortedParams.Add("version", "0.0.1"); //版本号
        sortedParams.Add("encoding", "UTF-8"); //编码方式
        sortedParams.Add("signMethod", "02"); //签名方法

        Dictionary<string, string> bizContent = new Dictionary<string, string>();

        bizContent.Add("merId", MER_ID); //商户号
        bizContent.Add("orderId", "QY2023111515281002"); //商户订单号
        //bizContent.Add("origOrderId", "3089991074200OHtest1026521"); //商户订单号
        bizContent.Add("origCmbOrderId", "004123112015485492393964"); //cmb单号
        bizContent.Add("userId", USER_ID); //收银员
        bizContent.Add("notifyUrl", "https://qa-openapi.youzy.cn/youzy.tob.payment.order.cmb. "); //交易通知地址                           
        bizContent.Add("txnAmt", "1"); //交易金额
        bizContent.Add("refundAmt", "1"); //退款金额

        //bizContent.Add("body", "body"); //商品描述
        //bizContent.Add("tradeType", "JSAPI");  //交易类型    
        //bizContent.Add("tradeScene", "OFFLINE"); //交易场景   
        //bizContent.Add("spbillCreateIp", "127.0.0.1");
        //bizContent.Add("deviceInfo", "WEB"); //不是必传参数，PC 网页或公众号内支付请传"WEB"  
        //bizContent.Add("subAppId", SUB_APPID);
        //bizContent.Add("subOpenId", SUB_OPENID);

        //排序
        bizContent = bizContent.OrderBy(m => m.Key).ToDictionary(p => p.Key, o => o.Value);

        sortedParams.Add("biz_content", JsonConvert.SerializeObject(bizContent));

        sortedParams.Add("sign", CMB_SignUtil.GetSign(sortedParams));

        Console.WriteLine("请求参数:");
        Console.WriteLine(JsonConvert.SerializeObject(sortedParams));
        Console.WriteLine("请求头:");
        Console.WriteLine(JsonConvert.SerializeObject(GetHeader(sortedParams)));

        Dictionary<string, string> result = CMB_WebUtil.PostForEntity(ApiUrl.Url_Orderquery, JsonConvert.SerializeObject(sortedParams), GetHeader(sortedParams));

        Console.WriteLine("响应参数:");
        Console.WriteLine(JsonConvert.SerializeObject(result));

        // 验签
        CMB_SignUtil.VerifySign(result);
    }

    #region 签名

    /// <summary>
    /// 签名
    /// </summary>
    /// <param name="sortedParams"></param>
    /// <returns></returns>
    public static string GetSign(Dictionary<string, string> sortedParams)
    {
        //排序拼接参数
        string signContent = CMB_SignUtil.GetSignContent(sortedParams);
        Console.WriteLine("待签名原文:");
        Console.WriteLine(signContent);
        //加签
        string sign = CMB_GmUtil.generateSmSign(signContent);
        Console.WriteLine("签名后值:");
        Console.WriteLine(sign);
        return sign;
    }

    #endregion 签名

    #region Http请求封装

    private static Dictionary<string, string> GetHeader(Dictionary<String, String> sortedParams)
    {
        long timestamp = ConvertDateTime(System.DateTime.Now) / 10000000;
        // 组apiSign加密Map
        Dictionary<string, string> apiSign = new Dictionary<string, string>();
        apiSign.Add("appid", APPID);
        apiSign.Add("secret", APP_SECRET);
        apiSign.Add("sign", sortedParams["sign"]);
        apiSign.Add("timestamp", "" + timestamp);

        // MD5加密
        String MD5Content = CMB_SignUtil.GetSignContent(apiSign);
        String apiSignString = GetMD5(MD5Content, "UTF-8");

        // 组request头部Map
        Dictionary<string, string> apiHeader = new Dictionary<string, string>();
        apiHeader.Add("appid", APPID);
        apiHeader.Add("timestamp", "" + timestamp);
        apiHeader.Add("apisign", apiSignString);


        return apiHeader;
    }

    private static long ConvertDateTime(System.DateTime time)
    {
        System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
        return time.Ticks - startTime.Ticks;
    }

    #endregion

    #region 加密

    public static string GetMD5(string data, String charset)
    {
        //MD5加密，同样的字符串在每次加密后的字符串是一样的
        byte[] bData = Encoding.GetEncoding(charset).GetBytes(data);
        var myMD5 = MD5.Create();
        bData = myMD5.ComputeHash(bData);
        StringBuilder sBuilder = new StringBuilder();
        for (int i = 0; i < bData.Length; i++)
        {
            //十六进制转成小写的英文字符
            sBuilder.Append(bData[i].ToString("x2"));
        }
        return sBuilder.ToString();
    }

    #endregion 加密

    public class wechat_h5
    {
        public h5_info h5_info { get; set; }
    }

    public class h5_info
    {
        public string type { get; set; }

        public string wap_url { get; set; }

        public string wap_name { get; set; }
    }

}



